package com.pms.framework;

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;


/**
 * <p>Title: AILiveHelp</p>
 *
 * <p>Description: Artificially Intelligent Live Help</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: Kofja</p>
 *
 * @author Amit Shah
 * @version 1.0
 * <pre>
 * This is the generic class implementing the XML Parser Code. Classes that need
 * to use the XML Parser can extend this class and provide its object as the
 * <i>DefaultHandler</i> for the SAX Parser. Also must provide the XML / AIML file
 * to parse. The Class extending this class must implement the abstract handling methods.
 * </pre>
 */
public abstract class XMLParser extends DefaultHandler {

    private String aXMLFile;
    private DefaultHandler aHandler;
    /**
     * Default constructor
     **/
    public XMLParser() {
    }

    /**
     * Constructor accepting the Aiml File and the Document Handler for parsing
     *
     * @param mAimlFile the file to be parsed
     * @param mHandler the handle of DefaultHandler
     **/
    public XMLParser(String mXMLFile, DefaultHandler mHandler) {
        this.setXMLFile(mXMLFile);
        this.setHandler(mHandler);
    }

    /**
     * Sets the AIML file to be parsed
     *
     * @param mAimlFile the file to be parsed
     **/
    public void setXMLFile(String mXMLFile) {
        this.aXMLFile = mXMLFile;
    }

    /**
     * Sets the handler that will be used for parsing
     *
     * @param mHandler the handler which will be used for parsing the AIML file
     **/
    public void setHandler(DefaultHandler mHandler) {
        this.aHandler = mHandler;
    }

    /**
     * This is the main method call for processing the XML file. This method
     * becomes invalid for running if in case either the <i>XML file</i> is not
     * set or <i>DefaultHandlet</i> is not set.
     *
     * @throws Exception
     */
    public void processFile() throws Exception {
        // Use the default (non-validating) parser
        SAXParserFactory factory = SAXParserFactory.newInstance();

        try {

            //Check wether the Aiml File is set for parsing or not
            if (this.aXMLFile == null) {
                throw new Exception(" Aiml File not Set for parsing ");
            }

            //Check wether the Default Handler is set for parsing or not
            if (this.aHandler == null) {
                throw new Exception(" Default Handler not Set for parsing ");
            }

            // Parse the input
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse(new File(this.aXMLFile), this.aHandler);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /**
     * Default method that handles the the StartDocument Event. It makse the call to
     * handelStartDoccument.
     **/
    public void startDocument(){
        this.handleStartDocument();
    }

    /**
     * Default method that handles the the StartDocument Event. It makse the
     * call to handelStartDoccument.
     */
    public void endDocument() {
        this.handleEndDocument();
    }

    /**
     * Default method for handling the <i>Start of Element</i> event. This
     * method internally makes call to <i>handleStartElement<i> method.
     *
     * @param mNamespaceURI The Namespace URI for the element
     * @param mSName String Name of the element
     * @param mQName Qualified Name of the element
     * @param mAttrs Attributes if any in the element
     */
    public void startElement(String mNamespaceURI,
                             String mSName, // simple name (localName)
                             String mQName, // qualified name
                             Attributes mAttrs) {

        this.handleStartElement(mNamespaceURI,
                                mSName, // simple name (localName)
                                mQName, // qualified name
                                mAttrs);
    }

    /**
     * Default method for handling the <i>End of Element</i> event. This
     * method internally makes call to <i>handleEndElement<i> method.
     *
     * @param mNamespaceURI The Namespace URI for the element
     * @param mSName String Name of the element
     * @param mQName Qualified Name of the element
     */
    public void endElement(String mNamespaceURI,
                             String mSName, // simple name (localName)
                             String mQName // qualified name
            ) {

        this.handleEndElement(mNamespaceURI,
                              mSName, // simple name (localName)
                              mQName // qualified name
                );
    }


    /**
     * Default method for handling the <i>Charecters found</i> event. This
     * method internally makes call to <i>handleString<i> method.
     *
     * @param mBuf char[]
     * @param mOffset int
     * @param mLen int
     */
    public void characters(char mBuf[], int mOffset, int mLen)  {
        String retString = new String(mBuf, mOffset, mLen);
        this.handleString(retString);
    }


//Abstract method definations
    /**
     * This is the method to be implemented by the user for handling the data
     * found in between the elements.
     *
     * @param mData Data that was found between the elements
     */
    abstract void handleString(String mData);

    /**
     * This is the method to be implemented by the user for handling the start
     * of the doccument event.
     */
    abstract void handleStartDocument();

    /**
     * This is the method to be implemented by the user for handling the end
     * of the doccument event.
     */
    abstract void handleEndDocument();

    /**
     * This is the method to be implemented by the user for handling the start
     * of the element event.
     *
     * @param mNamespaceURI The Namespace URI for the element
     * @param mSName String Name of the element
     * @param mQName Qualified Name of the element
     * @param mAttrs Attributes if any in the element
     */
    abstract void handleStartElement(String mNamespaceURI,
                                     String mSName, // simple name (localName)
                                     String mQName, // qualified name
                                     Attributes mAttrs);


    /**
     * This is the method to be implemented by the user for handling the start
     * of the element event.
     *
     * @param mNamespaceURI The Namespace URI for the element
     * @param mSName String Name of the element
     * @param mQName Qualified Name of the element
     */
    abstract void handleEndElement(String mNamespaceURI,
                                   String mSName, // simple name (localName)
                                   String mQName // qualified name
            );

}
